home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Very Best of Atari Inside
/
The Very Best of Atari Inside 1.iso
/
mint
/
mntlib43
/
mntlib
/
read.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-14
|
4KB
|
177 lines
/*
* _read: like read, but takes a long instead of an int. Written by
* Eric R. Smith and placed in the public domain.
*/
#include <fcntl.h>
#include <osbind.h>
#include <errno.h>
#include <ioctl.h>
#include <signal.h>
#include <unistd.h>
#include <support.h>
#include <mintbind.h>
#include "lib.h"
#define CTRL(x) (x & 0x1f)
#define UNDEF -1
struct tchars __tchars = {
CTRL('C'), /* interrupt */
CTRL('\\'), /* quit */
CTRL('Q'), /* start */
CTRL('S'), /* stop */
CTRL('D'), /* EOF */
'\r' /* alternate end of line */
};
struct ltchars __ltchars = {
CTRL('Z'), /* suspend */
CTRL('Y'), /* suspend after read */
CTRL('R'), /* reprint */
UNDEF, /* flush output */
UNDEF, /* erase word */
UNDEF /* quote next char */
};
/*
* BUGS: in tos, turning ECHO off but leaving RAW and CBREAK alone doesn't
* work properly
*/
long
_read(fd, buf, size)
int fd;
void *buf;
unsigned long size;
{
char *foo;
long r;
extern int __mint;
int indx;
int flags;
#ifdef EIO
long tty_pgrp;
long omask;
__Sigfunc osigt;
#endif
#ifdef EAGAIN
long wasready;
#endif
if (isatty(fd)) {
/* work around a bug in TOS; 4096 bytes should be plenty for terminal reads */
if (size > 4096) size = 4096;
indx = __OPEN_INDEX(fd);
if (indx < 0 || indx >= __NHANDLES)
indx = __NHANDLES - 1;
flags = __open_stat[indx].flags;
}
else
flags = -1;
if ( (__mint > 0) || (flags == -1) ||
( ((flags & (RAW|CBREAK|ECHO)) == ECHO) ) ) {
#ifdef EIO
if (__mint && _isctty(fd)) {
(void) Fcntl(fd, (long) &tty_pgrp, TIOCGPGRP);
if (tty_pgrp != Pgetpgrp()) {
#if 0
/* This isn't really what we mean here...we really want to
know if our process group has no controlling terminal.
*/
if (fd == -1 && __open_stat[indx] == FH_ISAFILE) {
errno = EIO;
return -1;
}
#endif
omask = Psigblock(~0L);
osigt = (__Sigfunc) Psignal(SIGTTIN, (long) SIG_IGN);
(void) Psignal(SIGTTIN, (long) osigt);
(void) Psigsetmask(omask);
if ((omask & sigmask(SIGTTIN)) || (osigt == SIG_IGN)) {
errno = EIO;
return -1;
}
}
}
#endif /* EIO */
#ifdef EAGAIN
if (__mint) {
(void)Fcntl(fd, &wasready, FIONREAD);
}
#endif
r = Fread(fd, size, buf);
#ifdef EAGAIN
if (__mint && r == 0 && wasready == 0
&& (Fcntl(fd, 0, F_GETFL) | O_NDELAY)) {
r = -EAGAIN;
}
#endif
if (r < 0) {
errno = (int) -r;
return -1;
}
/* watch out for TTYs */
if (__mint == 0 && isatty(fd)) {
foo = (char *)buf;
if (*foo == __tchars.t_eofc) /* EOF character? */
return 0;
/* for multibyte reads terminated by a CR, we add
the CR since TOS doesn't put it in for us
*/
if ((r < size) && (foo[r - 1] != '\r'))
{
foo[r] = '\r';
r++;
}
/* If the last char is a CR (either added above
or read from a single-byte Fread()) we translate
it according to the CRMOD setting
*/
if ((flags & CRMOD) && r && (foo[r - 1] == '\r')) {
foo[r - 1] = '\n';
Cconout('\n'); /* not quite right if fd != 0 */
}
}
}
else {
again:
r = _console_read_byte(fd) & 0x00ff;
if (flags & ECHO) {
_console_write_byte(fd, (int)r);
}
if (flags & CRMOD) {
if (r == '\r') r = '\n';
}
if (!(flags & RAW)) {
if (r == __tchars.t_intrc) {
raise(SIGINT);
goto again;
}
else if (r == __tchars.t_quitc) {
raise(SIGQUIT);
goto again;
}
}
*((char *)buf) = r;
r = 1;
}
return r;
}
#if defined (__GNUC__) && !defined (__MSHORT__)
__asm__ (".stabs \"_read\",5,0,0,__read");
#else
int
read(fd, buf, size)
int fd;
void *buf;
unsigned size;
{
return (int) _read(fd, buf, (unsigned long)size);
}
#endif